#import <UIKit/UIKit.h>
#import <Security/Security.h>
#import <sqlite3.h>
#import <GCDWebServers/GCDWebServerDataResponse.h>
#import <GCDWebServers/GCDWebServerErrorResponse.h>
#import <GCDWebServers/GCDWebServerDataRequest.h>
#import <GCDWebServers/GCDWebServerStreamedResponse.h>
#import <GCDWebServers/GCDWebsocketServer.h>
#import <signal.h>
#import "kern_memorystatus.h"

/*
功能：
1.清空钥匙串信息
2.获取钥匙串所有的组信息
3.删除指定组钥匙串信息
*/


void deleteKeychainObjectsForGroup(NSString * group)
{

	sqlite3 *database;
	int openResult = sqlite3_open("/private/var/Keychains/keychain-2.db", &database);

	if (openResult == SQLITE_OK)
	{
		const char *deleteGenpSQL = [[NSString stringWithFormat:@"DELETE FROM genp WHERE agrp like '%%%@%%' COLLATE NOCASE;", group] UTF8String];
		const char *deleteCertSQL = [[NSString stringWithFormat:@"DELETE FROM cert WHERE agrp like '%%%@%%' COLLATE NOCASE;", group] UTF8String];
		const char *deleteKeysSQL = [[NSString stringWithFormat:@"DELETE FROM keys WHERE agrp like '%%%@%%' COLLATE NOCASE;", group] UTF8String];
		
		sqlite3_exec(database, deleteGenpSQL, NULL, NULL, NULL);

		sqlite3_exec(database, deleteCertSQL, NULL, NULL, NULL);

		sqlite3_exec(database, deleteKeysSQL, NULL, NULL, NULL);

		sqlite3_exec(database, "DELETE FROM inet;", NULL, NULL, NULL);

		sqlite3_exec(database, "DELETE FROM sqlite_sequence;", NULL, NULL, NULL);

        sqlite3_exec(database, "VACUUM;", NULL, NULL, NULL);
	
		sqlite3_close(database);
	}
}


void deleteAllKeychainObjects()
{
	sqlite3 *database;
	int openResult = sqlite3_open("/private/var/Keychains/keychain-2.db", &database);
	if (openResult == SQLITE_OK)
	{
		sqlite3_exec(database, "DELETE FROM genp WHERE agrp <> 'apple';", NULL, NULL, NULL);

		sqlite3_exec(database, "DELETE FROM cert WHERE agrp <> 'lockdown-identities';", NULL, NULL, NULL);

		sqlite3_exec(database, "DELETE FROM keys WHERE agrp <> 'lockdown-identities';", NULL, NULL, NULL);

		sqlite3_exec(database, "DELETE FROM inet;", NULL, NULL, NULL);

		sqlite3_exec(database, "DELETE FROM sqlite_sequence;", NULL, NULL, NULL);
		
        sqlite3_exec(database, "VACUUM;", NULL, NULL, NULL);
		
        sqlite3_close(database);
	}

}
int callback(void* data, int n_columns, char** col_values, char** col_names){
  NSMutableArray * results = (NSMutableArray*)data;
  for(int i = 0; i<n_columns; i++){
	NSString * string = [NSString stringWithFormat:@"%s",col_values[i]];
	if(![string hasPrefix:@"com.apple."]&&![string isEqualToString:@"apple"]&&![results containsObject:string])
	{
		[results addObject:string];
	}
  }
  return 0;
}
NSArray * getAllKeychainGroups()
{
	const char * dbPath = "/var/Keychains/keychain-2.db";

    sqlite3 *db;
	char *zErrMsg = 0;
	int rc;
    rc = sqlite3_open(dbPath, &db);
	if(rc != SQLITE_OK)
	{
		fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
		return nil;
	}

	fprintf(stdout, "Opened database successfully\n");
	NSMutableArray * results = [[NSMutableArray alloc]init];
	rc = sqlite3_exec(db, "SELECT DISTINCT agrp FROM genp", callback, (void*)results, &zErrMsg);
	if( rc != SQLITE_OK ){
		fprintf(stderr, "SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}
	rc = sqlite3_exec(db, "SELECT DISTINCT agrp FROM cert", callback, (void*)results, &zErrMsg);
	if( rc != SQLITE_OK ){
		fprintf(stderr, "SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}
	rc = sqlite3_exec(db, "SELECT DISTINCT agrp FROM inet", callback, (void*)results, &zErrMsg);
	if( rc != SQLITE_OK ){
		fprintf(stderr, "SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}
	rc = sqlite3_exec(db, "SELECT DISTINCT agrp FROM keys", callback, (void*)results, &zErrMsg);
	if( rc != SQLITE_OK ){
		fprintf(stderr, "SQL error: %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}
	
	sqlite3_close(db);
	//不用释放
	return results;
}

GCDWebServerDataResponse* dataResponse(NSDictionary *jsonData)
{
    GCDWebServerDataResponse *response = [GCDWebServerDataResponse responseWithJSONObject:jsonData];
    [response setValue:@"*" forAdditionalHeader:@"Access-Control-Allow-Origin"];       
    [response setValue:@"Content-Type" forAdditionalHeader:@"Access-Control-Allow-Headers"];   
    return response;
}
void initHandle(GCDWebsocketServer *webServer)
{
	[webServer addHandlerForMethod:@"GET" path:@"/datas" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) {
        NSDictionary *response = @{
                    @"status": @"success",
                    @"data": getAllKeychainGroups()
            };
        return dataResponse(response);
    }];

	[webServer addHandlerForMethod:@"GET" path:@"/removeAll" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) {
		deleteAllKeychainObjects();

        NSDictionary *response = @{
                    @"status": @"success"
            };
        return dataResponse(response);
    }];

	[webServer addHandlerForMethod:@"GET" path:@"/remove" requestClass:[GCDWebServerRequest class] processBlock:^GCDWebServerResponse *(GCDWebServerRequest *request) {
		NSString *key = request.query[@"key"];
        // clearKeychainItemsForBundleID(key);
		deleteKeychainObjectsForGroup(key);
		NSDictionary *response = @{
			@"status": @"success"
		};
        return dataResponse(response);
    }];
}
// 信号处理函数
void handleSignal(int signal) {
    NSLog(@"Received signal %d, shutting down...", signal);
    exit(0);
}
int main(int argc, char **argv, char **envp) {
    int rc;
    
    memorystatus_priority_properties_t props = {0, JETSAM_PRIORITY_CRITICAL};
    rc = memorystatus_control(MEMORYSTATUS_CMD_SET_PRIORITY_PROPERTIES, getpid(), 0, &props, sizeof(props));
    if (rc < 0) { perror ("memorystatus_control"); exit(rc);}
    
    rc = memorystatus_control(MEMORYSTATUS_CMD_SET_JETSAM_HIGH_WATER_MARK, getpid(), -1, NULL, 0);
    if (rc < 0) { perror ("memorystatus_control"); exit(rc);}
    
    rc = memorystatus_control(MEMORYSTATUS_CMD_SET_PROCESS_IS_MANAGED, getpid(), 0, NULL, 0);
    if (rc < 0) { perror ("memorystatus_control"); exit(rc);}
    
    rc = memorystatus_control(MEMORYSTATUS_CMD_SET_PROCESS_IS_FREEZABLE, getpid(), 0, NULL, 0);
    if (rc < 0) { perror ("memorystatus_control"); exit(rc); }

	@autoreleasepool {
        // 注册信号处理
        signal(SIGINT, handleSignal);
        signal(SIGTERM, handleSignal);
        
        GCDWebsocketServer *webServer = [[GCDWebsocketServer alloc] init];
        initHandle(webServer);
        
        NSError *error = nil;
        BOOL success = [webServer startWithOptions:@{
            GCDWebServerOption_Port: @(8083),
            GCDWebServerOption_BindToLocalhost: @NO,
            GCDWebServerOption_AutomaticallySuspendInBackground: @NO
        } error:&error];
        
        if (success) {
            NSLog(@"GCDWebServer running on %@", webServer.serverURL);
            NSLog(@"Press Ctrl+C to stop the server");
        } else {
            NSLog(@"Failed to start web server: %@", error);
            return 1;
        }
        
        // 保持运行
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}


